package ecustom.common.util;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.AccessController;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import sun.security.action.GetPropertyAction;
import weaver.general.MD5;

public class CustomUtil {

	public static final String DEFAULT_CHARSET_NAME = "UTF-8";
	private static final Logger log = Logger.getLogger(CustomUtil.class);

	public static Double add(double... values) {
		BigDecimal total = new BigDecimal(0);
		for (double value : values)
			total = total.add(new BigDecimal(value));
		return total.doubleValue();
	}
	
	public static String getLocalIP() {
		try {
			List<String> list = new ArrayList<>();
			Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();

			// 遍历所有的网络接口
			while (nis.hasMoreElements()) {
				NetworkInterface inter = nis.nextElement();

				Enumeration<InetAddress> ips = inter.getInetAddresses();
				while (ips.hasMoreElements()) {
					InetAddress ip = ips.nextElement();
					if (ip.getHostAddress().indexOf(".") <= 0) continue ;
					if (ip.getHostAddress().equals("127.0.0.1")) continue ;
					if (ip.getHostAddress().equals("2.0.0.1")) continue ;
					list.add(ip.getHostAddress());
				}
			}
			return CustomUtil.join(list, ",");	
		} catch (Exception e) {
			log.error("getLocalIP() Exception", e);
		}

		return "";		
	}
	
	public static Long getLong(Object value) {
		return getLong(value, null);
	}
	
	public static Long getLong(Object value, Long defValue) {
		if (value instanceof Long)
			return (Long) value;
			
		if (isBlank(value)) {
			log.error("getLong() error, value is blank!");
			return defValue;
		}
		
		if (!RegularUtil.isInt(value.toString())) {
			log.error("getLong() error, value[" + value + "] is not a integer");
			return defValue;
		}
		
		try {
			return Long.parseLong(getString(value));
		} catch (Exception e) {
			log.error("getLong() ", e);
		}
		return null;
	}

	public static String getStringDate() {
		return getStringDate("yyyy-MM-dd");
	}

	public static String getStringDate(String format) {
		return getStringDate(new Date(), format);
	}

	public static String getStringDate(Date date, String format) {
		return new SimpleDateFormat(format).format(date);
	}

	public static String join(List<?> list, String ch) {
		if (list == null || list.isEmpty()) return "";
		StringBuffer sb = new StringBuffer();
		for (Object value : list) {
			sb.append(ch).append(value);
		}
		return sb.substring(ch.length()).toString();
	}

	public static String getString(Object value) {
		return value == null ? "" : value.toString();
	}

	public static String getString(Object value, String devValue) {
		return value == null ? devValue : value.toString();
	}

	public static boolean isBlank(Object v) {
		return v == null || v.toString().trim().length() == 0;
	}

	public static Integer getInteger(Object value) {
		return getInteger(value, null);
	}

	public static Integer getInteger(Object value, Integer defValue) {
		if (value instanceof Integer)
			return (Integer) value;
			
		if (isBlank(value)) {
			log.error("getInteger() error, value is blank!");
			return defValue;
		}
		
		if (!RegularUtil.isInt(value.toString())) {
			log.error("getInteger() error, value[" + value + "] is not a integer");
			return defValue;
		}
		
		try {
			return Integer.parseInt(getString(value));
		} catch (Exception e) {
			log.error("getInteger() error, value[" + value + "] is not a integer");
		}
		return defValue;
	}

	public static String upperFirstChar(String str) {
		String firstChar = str.substring(0, 1).toUpperCase();
		return firstChar + str.substring(1);
	}

	public static boolean isNotBlank(Object v) {
		return !isBlank(v);
	}
	
	public static String genMD5(Map<?, ?> map, String... keys) {
		if (map == null || map.isEmpty()) {
			return new MD5().getMD5ofStr("");
		}
		StringBuilder src = new StringBuilder();
		for (String key : keys) {
			src.append(map.get(key));
		}
		return new MD5().getMD5ofStr(src.toString());
	}
	
	public static String genMD5(Map<?, ?> map, List<String> keys) {
		if (map == null || map.isEmpty()) {
			return new MD5().getMD5ofStr("");
		}
		StringBuilder src = new StringBuilder();
		for (String key : keys) {
			src.append(map.get(key));
		}
		return new MD5().getMD5ofStr(src.toString());
	}

	public static Double getDouble(Object v) {
		return v == null ? null : getDouble(v, null);
	}
	
	public static Double getDouble(Object value, Double defValue) {
		if (value instanceof Double)
			return (Double) value;
			
		if (isBlank(value)) {
			log.error("getDouble() error, value is blank!");
			return defValue;
		}
		
		if (!RegularUtil.isNumber(value.toString())) {
			log.error("getDouble() error, value[" + value + "] is not a number");
			return defValue;
		}
		
		try {
			return Double.parseDouble(value.toString());
		} catch (Exception e) {
			log.error("getDouble() error, value[" + value + "] is not a number");
		}
		return defValue;
	}
	
	public static Double getDoubleCK(Object v, String errMsg) {
		Double value = getDouble(v, null);
		if (value == null) throw new RuntimeException(errMsg);
		return value;
	}

	public static int getInt(Object v) {
		return getInt(v, -1);
	}
	
	public static int getInt(Object v, Integer defValue) {
		if (v == null) return defValue;
		try {
			return Integer.parseInt(v.toString());
		} catch (Exception e) {
			return defValue;
		}
	}

	public static int getIntCK(Object v, String msg) {
		if (v == null) throw new RuntimeException(msg);
		try {
			return Integer.parseInt(v.toString());
		} catch (Exception e) {
			throw new RuntimeException(msg);
		}
	}

	public static String getStringCK(Object obj, String msg) {
		if (obj == null) throw new IllegalArgumentException(msg);
		if (obj.toString().isEmpty())  throw new IllegalArgumentException(msg);
		return obj.toString();
	}
    
    public static String getEncoding() {
        return getEncoding(null);
    }
    
    public static String getEncoding(String encoding) {
        return getEncoding(encoding, null);
    }
    
    public static String getEncoding(String encoding, String defEncoding) {
        if (isNotBlank(encoding))
            return encoding;
        if (isNotBlank(defEncoding))
            return defEncoding;
        return AccessController.doPrivileged(new GetPropertyAction("file.encoding"));
    }
	
	public static String left(String str, int length) {
		if (str == null)
			return "";
		
		if (str.length() < length)
			return str;
		
		return str.substring(0, length);
	}

	public static String leftByBit(String str, int length, String charSet) {
		if (str == null) {
			return "";
		}
		int subLen = 0, chiLen = 0;
		if ("UTF-8".equalsIgnoreCase(charSet)) {
			chiLen = 3;
		}
		if ("GBK".equalsIgnoreCase(charSet)) {
			chiLen = 2;
		}
		if ("GB2312".equalsIgnoreCase(charSet)) {
			chiLen = 2;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char charAt = str.charAt(i);
			if (subLen + (charAt > 128 ? chiLen : 1) >= length) {
				break;
			}
			sb.append(charAt);
			subLen += charAt > 128 ? chiLen : 1;
		}
		return sb.toString();
	}
}
